package com.zhongli.devplatform.controller.common;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhongli.devplatform.bean.SecurityHelper;
import com.zhongli.devplatform.dto.common.ClazzDTO;
import com.zhongli.devplatform.dto.student.RemoveStudentDTO;
import com.zhongli.devplatform.dto.student.StudentDTO;
import com.zhongli.devplatform.dto.teacher.TransClazzDTO;
import com.zhongli.devplatform.enums.GradeTypeEnum;
import com.zhongli.devplatform.po.common.ReadClazzPO;
import com.zhongli.devplatform.po.common.ReadGradePO;
import com.zhongli.devplatform.po.common.ReadTeachClazzPO;
import com.zhongli.devplatform.po.user.ReadUserInfoPO;
import com.zhongli.devplatform.po.user.ReadUserPO;
import com.zhongli.devplatform.query.sys.ClazzQuery;
import com.zhongli.devplatform.service.imp.common.ReadTeachClazzService;
import com.zhongli.devplatform.service.imp.common.ReadClazzService;
import com.zhongli.devplatform.service.imp.user.ReadUserInfoService;
import com.zhongli.devplatform.service.imp.user.ReadUserService;
import com.zhongli.devplatform.service.imp.view.ViewUserToSchoolPOService;
import com.zhongli.devplatform.utils.BeanCopierUtil;
import com.zhongli.devplatform.utils.user.ShareCodeUtils;
import com.zhongli.devplatform.bean.Res;
import com.zhongli.devplatform.vo.common.ClazzVO;
import com.zhongli.devplatform.vo.student.StudentVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author WuXiCheng
 * @version 1.0
 * @date 2020/7/24 11:33
 */
@Api(tags = "班级app", description = "班级app", value = "班级app")
@RestController
@RequestMapping("/class")
@Slf4j
public class ClazzController {

    @Resource
    private ReadClazzService clazzService;

    @Autowired
    private ReadTeachClazzService teachClazzService;

    @Autowired
    private ReadUserService userService;

    @Autowired
    private ReadUserInfoService userInfoService;

    /**
     * 根据年级查询出所有的班级
     * @param id
     * @return
     */
    @ApiOperation("根据年级查询出所有的班级")
    @GetMapping("/allClazzInfoByGrade/{id}")
    public Res<List<ReadClazzPO>> getAllClazzByGrade(@PathVariable Integer id){
        Integer currentUserId = SecurityHelper.getCurrentUserId();
        ReadUserPO readUserPO = userService.getById(currentUserId);
        List<ReadClazzPO> data = clazzService.getAllClazzByGrade(currentUserId,id,readUserPO.getSchoolId());
        return Res.ok(data);
    }

    @ApiOperation("查询老师班主任创建班级所需班级列表")
    @GetMapping("/adminTeacherClazzList/{gradeId}")
    public Res<List<ClazzVO>> adminTeacherClazzList(@PathVariable("gradeId") Integer gradeId){
        Integer currentUserId = SecurityHelper.getCurrentUserId();
        List<ReadTeachClazzPO> teachers = teachClazzService.list(new QueryWrapper<ReadTeachClazzPO>().eq("teacher_id", currentUserId).eq("is_admin_teacher",true));
        List<ClazzVO> clazzVOS = new ArrayList<>();
        if(!teachers.isEmpty()){
            List<Integer> clazzIds = teachers.stream().map(ReadTeachClazzPO::getClazzId).collect(Collectors.toList());
            List<ReadClazzPO> clazzPOS = clazzService.list(new QueryWrapper<ReadClazzPO>().eq("grade_id",gradeId).in("id",clazzIds));
            clazzVOS = BeanCopierUtil.copy(clazzPOS, ClazzVO.class);
            assert clazzVOS != null;
            clazzVOS = clazzVOS.stream().filter(item -> StringUtil.isBlank(item.getInvitationCode())).collect(Collectors.toList());
            return Res.ok(clazzVOS);
        }
        return Res.ok(clazzVOS);
    }

    /**
     * 查询班级详情
     */
    @ApiModelProperty("查询班级详情")
    @ApiImplicitParam(name = "id", value = "班级id", required = true)
    @GetMapping("/queryClazzDetails")
    public Res queryClazzDetails(@RequestParam("id") Integer id){
        ReadClazzPO clazzPO = clazzService.getById(id);
        if (Objects.isNull(clazzPO)){
            return Res.not_ok("班级不存在");
        }
        //所在班级所有学生
        List<ReadUserPO> userPOS = userService.list(new QueryWrapper<ReadUserPO>().eq("clazz_id", clazzPO.getId()).eq("category",0));
        List<StudentVO> studentVOS = new ArrayList<>();
        for (ReadUserPO userPO : userPOS) {
            StudentVO studentVO = new StudentVO();
            studentVO.setId(userPO.getId());
            studentVO.setClassName(clazzPO.getClassName());
            studentVO.setNickName(userInfoService.getOne(new QueryWrapper<ReadUserInfoPO>().eq("user_id",userPO.getId())).getNickName());
            studentVOS.add(studentVO);
        }
        return Res.ok(studentVOS);
    }

    @ApiOperation("老师操作学生加入班级")
    @PostMapping("/joinClazz")
    public Res joinClazz(@RequestBody ClazzDTO clazzDTO){
        return clazzService.joinClazz(clazzDTO);
    }

    /**
     * 查询老师所任课的班级列表
     * @param gradeId 年级id
     * @return
     */
    @ApiOperation("根据年级年别班级查询老师所任课的班级列表")
    @GetMapping("/getClazzList")
    public Res<List<ClazzVO>> getClazzList(@RequestParam(value = "gradeId") Integer gradeId,
                                           @RequestParam("gradeType") Integer gradeType){
        return clazzService.getCurrentClazzList(gradeId,gradeType);
    }

    /**
     * 创建班级
     * @param clazzDTO
     * @return
     */
    @ApiOperation("创建班级")
    @PostMapping("/createClass")
    public Res createClass(@RequestBody ClazzDTO clazzDTO){
        Integer currentUserId = SecurityHelper.getCurrentUserId();
        ReadTeachClazzPO teachClazzPO = teachClazzService.getOne(new QueryWrapper<ReadTeachClazzPO>()
                .eq("teacher_id", currentUserId)
                .eq("clazz_id", clazzDTO.getId()).eq("is_admin_teacher",true));
        if (Objects.isNull(teachClazzPO)){
            return Res.not_ok("您不是班主任，无法创建班级");
        }
        ReadClazzPO clazzPO = BeanCopierUtil.copy(clazzDTO, ReadClazzPO.class);
        //生成邀请码
        String code = getCode(clazzPO);
        clazzService.updateById(clazzPO);

        return new Res<>(0,"创建成功",code);
    }

    /**
     * 实体类封装邀请码
     * @param clazzPO
     */
    private String getCode(ReadClazzPO clazzPO) {
        String code = "";
        boolean or = true;
        //校验数据库是否存在相同邀请码
        while (or){
            //生成班级邀请码
            code = ShareCodeUtils.idToCode(clazzPO.getId());
            List<ReadClazzPO> clazzPOS = clazzService.list(new QueryWrapper<ReadClazzPO>().eq("invitation_code",code));
            if(clazzPOS.size() == 0){
                clazzPO.setInvitationCode(code);
                or = false;
            }
        }
        return code;
    }

    /**
     * 转让班级
     * @param transClazzDTO
     * @return
     */
    @ApiOperation("转让班级")
    @PostMapping("/transClass")
    public Res transClass(@RequestBody TransClazzDTO transClazzDTO){
        return clazzService.transClass(transClazzDTO);
    }

    /**
     * 移除班级学生
     * @param removeStudentDTO
     * @return
     */
    @ApiOperation("移除班级学生")
    @PostMapping("/removeStudent")
    public Res removeStudent(@RequestBody RemoveStudentDTO removeStudentDTO){
        return clazzService.removeStudent(removeStudentDTO.getClazzId(),removeStudentDTO.getStudentId());
    }
}
